﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace QuickDev.Common.Utils
{
    public class ScoketRequests
    {
        private static readonly int PAGE_BUFFER_SIZE = 400000;

        private static string Recv( Socket sock , Encoding encode )
        {
            Byte[] buffer = new Byte[PAGE_BUFFER_SIZE];
            StringBuilder sb = new StringBuilder();

            Thread.Sleep( 300 );

            Int32 len = sock.Receive( buffer );
            sb.Append( encode.GetString( buffer , 0 , len ) );

            while ( sock.Available > 0 )
            {
                Thread.Sleep( 300 );

                Array.Clear( buffer , 0 , buffer.Length );
                len = sock.Receive( buffer );
                sb.Append( encode.GetString( buffer , 0 , len ) );
                string ss = encode.GetString( buffer , 0 , len );
            }
            sock.Close();
            return sb.ToString();
        }

        private static string MakeRequest( string serverUrl , string pageUrl , string submitMethod , string parametersData , string refererUrl , string cookies , Encoding encode )
        {
            string _url = string.Empty;
            if ( String.IsNullOrEmpty( pageUrl ) )
            {
                _url = "/";
            }
            else if ( pageUrl.Substring( 0 , 1 ) != "/" )
            {
                _url = "/" + pageUrl;
            }
            else
            {
                _url = pageUrl;
            }
            string formatString = string.Empty;
            string sendString = string.Empty;

            if ( submitMethod == RequestMethod.Get )
            {
                formatString += "{0} {1} HTTP/1.1\r\n";
                formatString += "Host: {2}\r\n";
                formatString += String.Format( "User-Agent:Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6) Gecko/{0} Firefox/3.6.6\r\n" , DateTime.Today.ToShortDateString() );
                formatString += "Accept: text/html\r\n";
                formatString += "Keep-Alive: 300\r\n";
                formatString += "Cookies:{3}\r\n";
                formatString += "Connection: keep-alive\r\n\r\n";
                sendString = string.Format( formatString , RequestMethod.Get , _url , serverUrl , cookies );
            }
            else
            {
                formatString += "{0} {1} HTTP/1.1\r\n";
                formatString += "Host: {2}\r\n";
                formatString += String.Format( "User-Agent:Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6) Gecko/{0} Firefox/3.6.6\r\n" , DateTime.Today.ToShortDateString() );
                formatString += "Accept:text/html\r\n";
                formatString += "Content-Type:application/x-www-form-urlencoded\r\n";
                formatString += "Content-Length:{3}\r\n";
                formatString += "Referer:{4}";
                formatString += "Keep-Alive:300\r\n";
                formatString += "Cookies:{5}\r\n";
                formatString += "Connection: keep-alive\r\n\r\n";
                formatString += "{6}\r\n";
                sendString = string.Format( formatString , RequestMethod.Post , _url , serverUrl , Encoding.Default.GetByteCount( parametersData ) , cookies , parametersData );
            }

            Byte[] ByteGet = encode.GetBytes( sendString );
            Byte[] RecvBytes = new Byte[PAGE_BUFFER_SIZE];
            String strRetPage = null;
            IPAddress hostadd = Dns.GetHostEntry( serverUrl ).AddressList[0];
            IPEndPoint EPhost = new IPEndPoint( hostadd , 80 );
            Socket s = new Socket( AddressFamily.InterNetwork , SocketType.Stream , ProtocolType.Tcp );
            s.Connect( EPhost );
            if ( !s.Connected )
            {
                strRetPage = "Cannot connect to the server url.";
                return strRetPage;
            }
            s.Send( ByteGet , ByteGet.Length , SocketFlags.None );

            strRetPage = Recv( s , encode );

            return strRetPage;
        }

        /// <summary>
        /// SocketGet( string serverUrl , string pageUrl , Encoding encode )
        /// </summary>
        /// <param name="serverUrl">serverUrl</param>
        /// <param name="pageUrl">pageUrl</param>
        /// <param name="encode">encode</param>
        /// <returns></returns>
        public static string SocketGet( string serverUrl , string pageUrl , Encoding encode )
        {
            return MakeRequest( serverUrl , pageUrl , RequestMethod.Get , String.Empty , String.Empty , String.Empty , encode );
        }

        /// <summary>
        /// SocketPost( string serverUrl , string pageUrl , string submitMethod , string parametersData , string refererUrl , string cookies , Encoding encode )
        /// </summary>
        /// <param name="serverUrl">serverUrl</param>
        /// <param name="pageUrl">pageUrl</param>
        /// <param name="submitMethod">submitMethod</param>
        /// <param name="parametersData">parametersData</param>
        /// <param name="refererUrl">refererUrl</param>
        /// <param name="cookies">cookies</param>
        /// <param name="encode">encode</param>
        /// <returns></returns>
        public static string SocketPost( string serverUrl , string pageUrl , string submitMethod , string parametersData , string refererUrl , string cookies , Encoding encode )
        {
            return MakeRequest( serverUrl , pageUrl , RequestMethod.Post , parametersData , refererUrl , cookies , encode );
        }
    }
}
